#!/usr/bin/env sh

command="${1}"
if [ "${command}" = "rm" ]; then
    command="remove"
fi
if [ "$#" -gt 0 ]; then shift; fi
subcommand="${1}"

# Try to figure out what the project root directory is
project_root=$(pwd)
while [ ! -d "${project_root}/.db" ]; do

  if [ "${project_root}" = "/" ]; then
    if [ "${command}" = "init" ]; then
      project_root=$(pwd)
      break
    else
      echo "fatal: Not a db repository (or any of the parent directories). Please run 'db init'.";
      exit 2
    fi
  fi

  project_root=$(cd "${project_root}/.." && pwd)
done


rreadlink() ( # Execute the function in a *subshell* to localize variables and the effect of `cd`.

  target=$1 fname= targetDir= CDPATH=

  # Try to make the execution environment as predictable as possible:
  # All commands below are invoked via `command`, so we must make sure that `command`
  # itself is not redefined as an alias or shell function.
  # (Note that command is too inconsistent across shells, so we don't use it.)
  # `command` is a *builtin* in bash, dash, ksh, zsh, and some platforms do not even have
  # an external utility version of it (e.g, Ubuntu).
  # `command` bypasses aliases and shell functions and also finds builtins
  # in bash, dash, and ksh. In zsh, option POSIX_BUILTINS must be turned on for that
  # to happen.
  { \unalias command; \unset -f command; } >/dev/null 2>&1
  [ -n "$ZSH_VERSION" ] && options[POSIX_BUILTINS]=on # make zsh find *builtins* with `command` too.

  while :; do # Resolve potential symlinks until the ultimate target is found.
      [ -L "$target" ] || [ -e "$target" ] || { command printf '%s\n' "ERROR: '$target' does not exist." >&2; return 1; }
      command cd "$(command dirname -- "$target")" # Change to target dir; necessary for correct resolution of target path.
      fname=$(command basename -- "$target") # Extract filename.
      [ "$fname" = '/' ] && fname='' # !! curiously, `basename /` returns '/'
      if [ -L "$fname" ]; then
        # Extract [next] target path, which may be defined
        # *relative* to the symlink's own directory.
        # Note: We parse `ls -l` output to find the symlink target
        #       which is the only POSIX-compliant, albeit somewhat fragile, way.
        target=$(command ls -l "$fname")
        target=${target#* -> }
        continue # Resolve [next] symlink target.
      fi
      break # Ultimate target reached.
  done
  targetDir=$(command pwd -P) # Get canonical dir. path
  # Output the ultimate target's canonical path.
  # Note that we manually resolve paths ending in /. and /.. to make sure we have a normalized path.
  if [ "$fname" = '.' ]; then
    command printf '%s\n' "${targetDir%/}"
  elif  [ "$fname" = '..' ]; then
    # Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied
    # AFTER canonicalization.
    command printf '%s\n' "$(command dirname -- "${targetDir}")"
  else
    command printf '%s\n' "${targetDir%/}/$fname"
  fi
)

# Get the directory where the main script (this one) is installed
export installation_root=$(dirname -- "$(rreadlink "$0")")

# Load the colors
export bin="${installation_root}/bin"
. "${bin}/include/colors"

# Default server alias is the server that was added first. If no servers exist yet, use "localhost"
alias="localhost"
if [ -d "${project_root}/.db" ]; then
  configs=$(find "${project_root}/.db" -mindepth 1 -maxdepth 1 -type d | wc -l)
  if [ ${configs} -gt 0 ]; then
    alias=$(find "${project_root}/.db" -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 ls -1drt | head -n 1 | rev | cut -f 1 -d '/' | rev)
  else
    if [ "${command}" != "server" ] && [ "${subcommand}" != "add" ]; then
      echo "${COLOR_RED}No database servers defined!${COLOR_NC}"
      echo "Please add a server configuration by typing ${COLOR_LIGHT_BLUE}db server add${COLOR_NC}"
      exit 1
    fi
  fi
fi

# Figure out if an alias has been provided on the command line
if [ "$#" -ge 1 ]; then
  # yes, perhaps
  if [ "${command}" = "server" ]; then
    # with the 'server' command, the alias is the third argument (server add XXX)
    if [ "$#" -ge 2 ]; then
      if [ -d "${project_root}/.db/${2}/config" ] || [ "${subcommand}" = "add" ]; then
        alias="${2}"
      fi
    fi
  else
    # with other commands, the alias is the second argument (snapshot XXX)
    if [ -d "${project_root}/.db/${1}/config" ]; then
      alias="${1}"
      shift
    fi
  fi
fi

# for synching database CONTENTS http://www.cri.ensmp.fr/~coelho/pg_comparator/pg_comparator.html
# for synching database STRUCTURE http://mmatuson.github.io/SchemaSync/ or http://search.cpan.org/dist/MySQL-Diff/bin/mysqldiff

cmd="${installation_root}/bin/db-${command}"
if [ -f "${cmd}" ]; then
  ${cmd} "${project_root}" "${alias}" "$@"
else
  commands=$(ls -1 "${installation_root}/bin" | grep "db-" | cut -d "-" -f 2 | paste -s -d "|" -)
  echo "USAGE:"
  echo "    ${COLOR_BLUE}db (${commands})${COLOR_NC}"
  exit 1
fi